

import UIKit
import ContactsUI
import Contacts

class FriendsViewController: UITableViewController {
  
  var friendsList = Friend.defaultContacts()
  
    @IBAction func addFriends(sender: UIBarButtonItem) {
        let contactPicker = CNContactPickerViewController()
        contactPicker.delegate = self
        contactPicker.predicateForEnablingContact = NSPredicate(format: "emailAddress.@count > 0")
        presentViewController(contactPicker, animated: true, completion: nil)
    }
  override func viewDidLoad() {
    super.viewDidLoad()
    navigationItem.titleView = UIImageView(image: UIImage(named: "RWConnectTitle")!)
    tableView?.rowHeight = UITableViewAutomaticDimension
    tableView?.estimatedRowHeight = 60
  }
  
}

//MARK: UITableViewDataSource
extension FriendsViewController {
  
  override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
  }
  
  override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return friendsList.count
  }
  
  override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("FriendCell", forIndexPath:indexPath)
    
    if let cell = cell as? FriendCell {
      let friend = friendsList[indexPath.row]
      cell.friend = friend
    }
    
    return cell
  }
  
  override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {}
    
    override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
        
        let createContact = UITableViewRowAction(style: .Normal, title: "Create Contact") { (rowaction, indexPath) -> Void in
            let contactStore = CNContactStore()
            contactStore.requestAccessForEntityType(CNEntityType.Contacts, completionHandler: { (userFrantedAccess, _) -> Void in
                guard userFrantedAccess else{
                    self.presentPremissionErrorAlert()
                    return
                }
                
                let friend = self.friendsList[indexPath.row]
                self.saveFriendToContacts(friend)
            })
        }
        createContact.backgroundColor = BlueColor
        return [createContact]
    }
    
    
  
}



extension FriendsViewController{
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        tableView.deselectRowAtIndexPath(indexPath, animated: true)
        
        //1
        let friend = friendsList[indexPath.row]
        let contact = friend.contactValue
        //2
        let contactViewController = CNContactViewController(forUnknownContact: contact)
        contactViewController.navigationItem.title = "Profile"
        contactViewController.hidesBottomBarWhenPushed = true
        //3
        contactViewController.allowsActions = false
        contactViewController.allowsEditing = false
        //4
        navigationController?.pushViewController(contactViewController, animated: true)
    }
}



extension FriendsViewController:CNContactPickerDelegate{
    func contactPicker(picker: CNContactPickerViewController, didSelectContacts contacts: [CNContact]) {
        let newFriends = contacts.map{Friend(contact: $0)}
        for friend in newFriends{
            if !friendsList.contains(friend){
                friendsList.append(friend)
            }
        }
        tableView.reloadData()
    }
}



extension FriendsViewController{
    func presentPremissionErrorAlert(){
        dispatch_async(dispatch_get_main_queue()) { () -> Void in
            let alert = UIAlertController(title: "Could Not Save Contact", message: "How an I supposed to add the contact if you didn't give me premission", preferredStyle: UIAlertControllerStyle.Alert)
            let openSettingsAction = UIAlertAction(title: "Settings", style: .Default, handler: { (alert) -> Void in
                //打开设置
                UIApplication.sharedApplication().openURL(NSURL(string: UIApplicationOpenSettingsURLString)!)
            })
            let dismissAction = UIAlertAction(title: "OK", style: .Cancel, handler: nil)
            
            alert.addAction(openSettingsAction)
            alert.addAction(dismissAction)
            
            self.presentViewController(alert, animated: true, completion: nil)
        }
    }
    
    
    func saveFriendToContacts(friend:Friend){
        //1 
        let contactFormatter = CNContactFormatter()
        //2
        let contactName = contactFormatter.stringFromContact(friend.contactValue)!
        //3
        let predicateForMatchingName = CNContact.predicateForContactsMatchingName(contactName)
        //4
        
        let matchingContacts = try! CNContactStore().unifiedContactsMatchingPredicate(predicateForMatchingName, keysToFetch: [])
        
        guard matchingContacts.isEmpty else{
            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                let alert = UIAlertController(title: "Contact Already Exists", message: nil, preferredStyle: .Alert)
                alert.addAction(UIAlertAction(title: "OK", style: .Cancel, handler: nil))
                self.presentViewController(alert, animated: true, completion: nil)
            })
            return
        }
        
        
        //1
        let contact = friend.contactValue.mutableCopy() as! CNMutableContact
        //2
        let saveRequest = CNSaveRequest()
        //3
        saveRequest.addContact(contact, toContainerWithIdentifier: nil)
        do {
                let contactStore = CNContactStore()
                try contactStore.executeSaveRequest(saveRequest)
            //show success alert
            dispatch_async(dispatch_get_main_queue()) {
                
                let successAlert = UIAlertController(title: "Contacts Saved", message: nil, preferredStyle: .Alert)
                
                successAlert.addAction(UIAlertAction(title: "OK", style: .Cancel, handler: nil))
                
                self.presentViewController(successAlert, animated: true, completion: nil)
            }
        }catch{
            //show failure alert
            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                let failureAlert = UIAlertController(title: "Could Not Save Contact", message: "An Unknown error occurred.", preferredStyle: .Alert)
                failureAlert.addAction(UIAlertAction(title: "OK", style: .Cancel, handler: nil))
                self.presentViewController(failureAlert, animated: true, completion: nil)
            })
        }
    }
}
